package com.trsvax.gwthello.services;

import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.InjectService;
import org.apache.tapestry5.services.Dispatcher;
import org.apache.tapestry5.services.LibraryMapping;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.urlrewriter.RewriteRuleApplicability;
import org.apache.tapestry5.urlrewriter.SimpleRequestWrapper;
import org.apache.tapestry5.urlrewriter.URLRewriteContext;
import org.apache.tapestry5.urlrewriter.URLRewriterRule;

import com.trsvax.gwthello.services.dispatcher.GWTRPCDispatcher;
import com.trsvax.tapestry.instrumentation.services.TapestryAppender;

/**
 * This module is automatically included as part of the Tapestry IoC Registry,
 * it's a good place to configure and extend Tapestry, or to place your own
 * service definitions.
 */
public class AppModule {
	public static void bind(ServiceBinder binder) {
		binder.bind(GWTRPCDispatcher.class).withId("gwtrpc");
		binder.bind(TapestryAppender.class).withId("log");
	}

	public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {
		// Contributions to ApplicationDefaults will override any contributions
		// to
		// FactoryDefaults (with the same key). Here we're restricting the
		// supported
		// locales to just "en" (English). As you add localised message catalogs
		// and other assets,
		// you can extend this list of locales (it's a comma separated series of
		// locale names;
		// the first locale name is the default when there's no reasonable
		// match).

		configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");

		// The factory default is true but during the early stages of an
		// application
		// overriding to false is a good idea. In addition, this is often
		// overridden
		// on the command line as -Dtapestry.production-mode=false
		String environment = System.getProperty("environment");
		if (environment == null)
			environment = "prod";

		if (environment.equals("dev")) {
			configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
		}
		if (environment.equals("prod")) {
			configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
		}

		// The application version number is incorprated into URLs for some
		// assets. Web browsers will cache assets because of the far future
		// expires
		// header. If existing assets are changed, the version number should
		// also
		// change, to force the browser to download new versions.
		configuration.add(SymbolConstants.APPLICATION_VERSION, "1.0-SNAPSHOT");
	}

	public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration,
			@InjectService("gwtrpc") Dispatcher gwtrpc) {
		configuration.add("gwtrpc", gwtrpc, "before:PageRender");
	}

	static final String codeServer = System.getProperty("codeServer");

	public static void contributeURLRewriter(OrderedConfiguration<URLRewriterRule> configuration) {

		if (codeServer != null) {
			URLRewriterRule rule = new URLRewriterRule() {
				public Request process(Request request, URLRewriteContext context) {
					// if this is a component event, getPageParameters() will
					// return null.
					if (context.getPageParameters() == null)
						return request;

					// not really right but good enough for dev
					String path = request.getPath() + "?gwt.codesvr=" + codeServer;
					return new SimpleRequestWrapper(request, path);
				}

				public RewriteRuleApplicability applicability() {
					return RewriteRuleApplicability.OUTBOUND;
				}
			};
			configuration.add("rule1", rule);
		}
	}

	public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
			@InjectService("log") TapestryAppender filter) {
		// Each contribution to an ordered configuration has a name, When
		// necessary, you may
		// set constraints to precisely control the invocation order of the
		// contributed filter
		// within the pipeline.

		configuration.add("log", filter);
	}

	public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration) {
		configuration.add(new LibraryMapping("i", "com.trsvax.tapestry.instrumentation"));
	}

}
